import { FormatFileSize, GetFileType } from '../../utils/index.ts'
import type { OptionsType, FileObjType, ChunkType } from '../../types/index.ts'
import { Message } from '../../hooks/Message.ts'

// 添加文件
async function addFile(files: FileList, options: OptionsType, Hooks: any, LogService: any, StoreService: any) {
  debugger
  if (StoreService.globalUploadStatus.value !== 'start')
    return Message('warning', '当前有任务在队列中，不允许重复点击', '方法 addFile')
  if (files.length <= 0) return Message('warning', '未识别到文件', '方法 addFile')

  let list: any[] = []
  list = Array.from(files).map((file: File, index) => {
    return {
      fileName: (file as File)?.name || '',
      fileHash: '',
      fileSize: (file as File)?.size || 0,
      fileType: GetFileType(file.name),
      chunkSize: options.chunkSize || 0,
      fileStatus: 'waiting',
      progress: 0,
      chunks: [],
      chunkList: [],
      fileSource: files[index],
      uploadedSize: 0, // 已上传大小
      startTime: 0, // 上传开始时间
      uploadedChunks: [], // 初始化已上传分片数组
      id: `file_${index}_${new Date().getTime()}`,
      uploadSpeed: '0 KB/s', // 上传速度
      remainingTime: '0秒', // 剩余时间
    } as FileObjType
  })
  const isAdd = list.some((item) => {
    if (!StoreService.fileList.value.some((i: any) => i.fileName === item.fileName)) {
      // 记录文件大小
      StoreService.filesTotalSize.value += item.fileSize

      if (StoreService.filesTotalSize.value >= options.maxTotalSize) {
        Message('warning', `一次上传的最大文件大小不能超过${FormatFileSize(options.maxTotalSize)}`)
        LogService.addLog(
          `添加文件: ${item.fileName} 失败，超过最大上传文件限制${FormatFileSize(options.maxTotalSize)}`,
          'warning',
        )
        debugger
        StoreService.filesTotalSize.value -= item.fileSize
        return true
      }

      StoreService.fileList.value.push(item)
    }
  })

  if (!isAdd) {
    debugger
    // 触发文件添加钩子
    await Hooks.executeHook('onFileSelected', {fileList: [...StoreService.fileList.value], fileLength: list.length})
  }
}

// 删除指定文件
function delFile(file: FileObjType, Queue: any, StoreService: any) {
  const index = StoreService.fileList.value.findIndex((i: any) => i.id === file.id)
  StoreService.fileList.value.splice(index, 1)
  StoreService.filesTotalSize.value -= file.fileSize
  Queue?.delTask(file.fileHash)
}
// 删除所有文件
function delAllFile(Queue: any, StoreService: any) {
  debugger
  StoreService.resetStore()
  // Store.fileList = []
  // Store.fileList.splice(0, Store.fileList.length)
  // Store.filesTotalSize = 0
  Queue?.resetAll()
}

// 暂停文件
function pause(file: FileObjType, StoreService: any) {
  StoreService.fileList.value.some((i: any) => {
    if (i.id === file.id) {
      i.fileStatus = 'paused'
      return
    }
  })
}

/**
 * 创建分片上传对象的工厂函数
 * @param {FileType} file - 文件
 * @param {number} chunkSize - 每个分片的大小（字节）
 */
function GenerateChunk(fileList: FileObjType[], chunkSize: number, Hooks: any, LogService: any) {
  return new Promise((resolve, reject) => {
    const _Hooks = Hooks
    try {
      fileList.forEach((fileItem, index) => {
        // 跳过已上传的文件
        if (fileItem.fileStatus == 'waiting') {
          // 分片
          let chunks: Blob[] = []
          for (
            let i = 0;
            i < (fileItem as { fileSource: { size: number } }).fileSource.size;
            i += chunkSize
          ) {
            chunks.push(
              (
                fileItem as { fileSource: { slice: (start: number, end?: number) => Blob } }
              ).fileSource.slice(i, i + chunkSize),
            )
          }

          // 生成分片哈希值
          const chunkIterator = chunks.entries()
          let totalChunks = chunks.length || 0

          // 分片上传对象列表
          const chunkList: ChunkType[] = []

          // 递归遍历分片，生成待上传分片列表
          async function itemForEach() {
            const nextValue = chunkIterator.next().value
            if (nextValue) {
              const [chunkNumber, chunkData] = nextValue

              const chunkObj: ChunkType = {
                fileHash: '',
                fileName: (fileItem as { fileName: string }).fileName,
                fileSize: (fileItem as { fileSize: number }).fileSize,
                chunkNumber,
                chunkHash: '',
                chunkData,
                chunkSize,
                totalChunks,
                uploaded: false, // 分片上传状态
                progress: 0,
                retryNum: 0, // 分片上传失败重试次数
                startTime: 0, // 上传开始时间
              }
              chunkList.push(chunkObj)
            }
            if (nextValue && nextValue[0] < totalChunks) {
              itemForEach()
            } else {
              // 分片结束
              debugger
              fileItem.chunkList = chunkList
              fileItem.chunks = chunks
          
              _Hooks?.executeHook('onFileChunking', fileItem)
              resolve(true)
            }
          }

          itemForEach()
        }
      })
    } catch (error) {
      reject(error)
    }
  })
}

export default { addFile, delFile, delAllFile, pause, GenerateChunk }
